<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        img{width:100px;}
        div{padding: 10px;margin: 10px;}
    </style>
</head>
<body>
</body>
<script>
    
    // 创建枝对象的组合器
    // 功能：创建一个容器类元素，添加一些标志，可以被添加子对象，定义需要向下传递的功能方法
    
    function Team(id){
        this.ele = document.createElement("div");
        this.ele.id = id;
        this.children = [];
    }
    Team.prototype = {
        constructor: Team,
        add(child){
            this.children.push(child);
            this.ele.appendChild(child.ele);
        },
        remove(child){
            // 从DOM结构中删除这个子对象的元素
            this.ele.removeChild(child.ele);
            // a:准备从所有子对象中找到当前传入的子对象
            // a1. 提前准备变量用来保存，可能出现的子对象对应的索引
            let i;
            // a2. 使用数组的some方法遍历所有子对象
            const flag = this.children.some((val,idx)=>{
                // a3. 将每个数组的索引都同步保存到外部变量
                i = idx;
                // a4. 一旦从数组中找到符合的子对象，some就被停止了。索引停留在找到的符合要求的子对象的索引上
                return val === child;
            })
            // 判断是否找到
            if(flag){
                // 删除对应的子对象
                this.children.splice(i, 1);
            }
        },
        addBorder(){
            this.ele.style.border = "solid 6px black";
            this.children.forEach(val=>{
                val.addBorder();
            })
        },
        removeBorder(){
            this.ele.style.border = "";
            this.children.forEach(val=>{
                val.removeBorder();
            })
        }
    }


    // 创建叶对象的组合器
    // 功能：创建一个非容器类元素，添加一些标志，不能添加子对象，不需要向下传递的功能方法，需要直接操作自身的方法。虽然没有一些枝对象的功能，但是一定要保持叶对象和枝对象方法和属性的一致
    
    function Item(src){
        this.ele = document.createElement("img")
        this.ele.src = src;
    }
    Item.prototype = {
        constructor: Item,
        add(child){
            console.error("这是一个叶对象，不能添加子对象了")
        },
        remove(child){
            console.error("这是一个叶对象，不能删除子对象了")
        },
        addBorder(){
            this.ele.style.border = "solid 6px black";
        },
        removeBorder(){
            this.ele.style.border = "";
        }
    }

    // 创建根容器
    const box = new Team("box");
    document.body.appendChild(box.ele);

    // 创建枝对象
    const box1 = new Team("box1")
    const box2 = new Team("box2")
    // 创建叶对象
    const img1 = new Item("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png")
    const img2 = new Item("https://img0.baidu.com/it/u=3798217922,3880088897&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1659114000&t=220b85b82b2083d52ff6705f4785a685")
    const img3 = new Item("https://img1.baidu.com/it/u=3217543765,3223180824&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1659114000&t=1cbf7e1bc6a37550b7044e6aa30c2166")


    // 组合
    box.add(box1);
    box.add(box2);
    box.add(img3);

    box1.add(img1);
    box2.add(img2);

    // 开始批处理
    box.addBorder();

    box2.removeBorder();

    img1.removeBorder();

    // img1.add();

    // div#box
    //     div#box1
    //         img
    //     div#box2
    //         img
    //     img


    // 捕获语法错误或执行错误
    // try {
    // } catch (error) {
    // }

</script>
</html>